[IA64] fixed a vcpu_translate bug
authorawilliam@xenbuild.aw <awilliam@xenbuild.aw>
Fri, 17 Mar 2006 21:06:20 +0000 (14:06 -0700)
committerawilliam@xenbuild.aw <awilliam@xenbuild.aw>
Fri, 17 Mar 2006 21:06:20 +0000 (14:06 -0700)
There are some below code segments in guest OS
1.     Rsm psr.dt
       ...
2.     itc.d r18
       ...
3.     rfi

After executing instruction 1, domain is in metaphysical mode.
When executing instruction 2, VMM gets control to emulate this
instruction. Firstly VMM will try to get opcode, which may
trigger a tlb miss. At this time domain is in metaphysical mode
and the fault address is in region 5. vcpu_translate handles this
as normal guest metaphysical mode.

It's not correct; sometimes this will make dom0 hang.

cpu_translate should handle this situation as if
guest is not in metaphysical mode.

Signed-off-by: Anthony Xu <anthony.xu@intel.com>
xen/arch/ia64/xen/vcpu.c

index 87470bda1b19ac14aefb1151e30741e190eb134c..763be05fee550a954b2b2bd76b024cb98a864177 100644 (file)
@@ -1283,13 +1283,23 @@ IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, BOOLEAN in
 // FIXME: This seems to happen even though it shouldn't.  Need to track
 // this down, but since it has been apparently harmless, just flag it for now
 //                     panic_domain(vcpu_regs(vcpu),
-                       printk(
-                        "vcpu_translate: bad physical address: 0x%lx\n",address);
+
+                       /*
+                        * Guest may execute itc.d and rfi with psr.dt=0
+                        * When VMM try to fetch opcode, tlb miss may happen,
+                        * At this time PSCB(vcpu,metaphysical_mode)=1,
+                        * region=5,VMM need to handle this tlb miss as if
+                        * PSCB(vcpu,metaphysical_mode)=0
+                        */           
+                       printk("vcpu_translate: bad physical address: 0x%lx\n",
+                              address);
+               } else {
+                       *pteval = (address & _PAGE_PPN_MASK) | __DIRTY_BITS |
+                                 _PAGE_PL_2 | _PAGE_AR_RWX;
+                       *itir = PAGE_SHIFT << 2;
+                       phys_translate_count++;
+                       return IA64_NO_FAULT;
                }
-               *pteval = (address & _PAGE_PPN_MASK) | __DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX;
-               *itir = PAGE_SHIFT << 2;
-               phys_translate_count++;
-               return IA64_NO_FAULT;
        }
        else if (!region && warn_region0_address) {
                REGS *regs = vcpu_regs(vcpu);